package com.orange.delivery.application.impl;

import java.util.List;
import java.util.Map;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.method.P;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;

import com.orange.delivery.application.ManageMarket;
import com.orange.delivery.business.ManageMarketBusiness;
import com.orange.delivery.model.MarketBean;
import com.orange.delivery.technicalservice.exception.InvalidMarketException;
import com.orange.delivery.technicalservice.exception.InvalidQueryException;
import com.orange.delivery.technicalservice.exception.NotFoundException;
import com.orange.delivery.technicalservice.exception.TechnicalException;
import com.orange.delivery.technicalservice.tool.MultiValuedMap;

/**
 * application implementation for market component
 * 
 * NB: in this small example, the application layer does nothing except forwarding to business layer. In more complex applications,
 * this layer should prepare all data for specific application provider.
 * 
 * NB : this layer defines transactions. All the methods in this class are transactional, we use the @Transactional annotation. We
 * could also use XML configuration annotation.
 * 
 * 
 * @author Clara
 */
public class ManageMarketImpl implements ManageMarket {

	private ManageMarketBusiness manageMarketBusiness;

	/**
	 * MarketBusiness setter filled by dependency injection
	 * 
	 * @param marketBusiness
	 *            the marketBusiness to inject
	 */
	public void setManageMarketBusiness(ManageMarketBusiness manageMarketBusiness) {
		this.manageMarketBusiness = manageMarketBusiness;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Map<Integer, MarketBean> findAllMarkets() throws NotFoundException, TechnicalException {
		return manageMarketBusiness.findAllMarkets();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	@Transactional(readOnly = true)
	public List<MarketBean> findMarketByName(String name) throws NotFoundException {
		return manageMarketBusiness.getMarketByName(name);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	@Transactional(readOnly = true)
	public long countMarketByName(String name) throws NotFoundException {
		return manageMarketBusiness.getMarketCountByName(name);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	@Transactional(readOnly = true)
	public Page<MarketBean> findMarketByName(Pageable pageInfo, String name) throws NotFoundException {
		return manageMarketBusiness.getMarketByName(pageInfo, name);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	@Transactional
	/* Spring Security authorization example. Already enforced with Wicket annotation @AuthorizeInstantiation("ROLE_ADMIN") on Market page */
	@PreAuthorize("hasRole('ROLE_ADMIN')")
	public Integer createMarket(MarketBean market) throws InvalidMarketException {
		return manageMarketBusiness.createMarket(market);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	@Transactional
	/* SPL Spring Security example : cannot modify market whose name is login name */ 
	@PreAuthorize("#m.name != authentication.name")
	public void modifyMarket(@P("m") MarketBean market) throws InvalidMarketException, NotFoundException {
		manageMarketBusiness.modifyMarket(market);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	@Transactional(readOnly = true)
	/* Spring Security authorization example. Already enforced with Wicket annotation @AuthorizeInstantiation("ROLE_ADMIN") on Market page */
	@PreAuthorize("hasRole('ROLE_ADMIN')")
	public void deleteMarket(int idMarket) throws InvalidMarketException {
		manageMarketBusiness.deleteMarket(idMarket);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	@Transactional(readOnly = true)
	public MarketBean consultMarket(int idMarket) throws InvalidMarketException, NotFoundException {
		return manageMarketBusiness.getMarket(idMarket);
	}

	@Override
	@Transactional(readOnly = true)
	public Page<MarketBean> findMarketByCriteria(Pageable pageInfo, MultiValuedMap<String, String> criteria)
			throws NotFoundException, InvalidQueryException {
		return manageMarketBusiness.findMarketByCriteria(pageInfo, criteria);
	}
}